/*******************************************************************************
 * This file is part of blueprint4j www.blueprint4j.org.
 * 
 *     blueprint4j is free software: you can redistribute it and/or modify
 *     it under the terms of the GNU Lesser General Public License as published by
 *     the Free Software Foundation, either version 3 of the License, or
 *     (at your option) any later version.
 * 
 *     blueprint4j is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *     GNU Lesser General Public License for more details.
 * 
 *     You should have received a copy of the GNU Lesser General Public License
 *     along with blueprint4j. If not, see <http://www.gnu.org/licenses/>.
 ******************************************************************************/
/**
* This is a utility class for 8583 library
* $Log: Utils.java,v $
* Revision 1.2  2004/09/14 13:55:11  travisb
* no message
*
* Revision 1.1.1.1  2004/04/22 12:56:14  travisb
* Fir
*
* Revision 1.1.1.1  2003/12/21 09:04:08  jaspervdb
* no message
*
* Revision 1.1.1.1  2003/10/20 15:30:48  travisb
* First import into CVS at Cellstop
*
* Revision 1.1.1.1  2003/03/30 15:25:28  tbulford
* no message
*
* Revision 1.1  2003/01/12 08:30:34  travis
* Import x MANY
*
* Revision 1.1.1.1  2002/12/16 22:14:01  jasper
* no message
*
* Revision 1.7  2002/09/21 10:48:11  travisb
* Fixed Build Dependancies.
*
* Revision 1.6  2002/09/16 10:10:48  travisb
* First version of DR Test Application
*
* Revision 1.5  2002/09/13 05:17:47  JasperV
* Commit for Version 1.0 Release 1
*
* Revision 1.4  2002/05/02 14:36:06  JasperV
* Commiter: NPPS Pins finished except for loading of MTN and CellC Pins
*
* Revision 1.3  2002/04/22 09:03:37  travisb
* Before Backup
*
* Revision 1.2  2002/02/27 09:18:36  travisb
* Changed the way that Protocols are handled they are now passed down from Comms Server to Comms and are forced into play from there.
*
* Revision 1.1  2002/02/20 13:30:43  JasperV
* First time add to new Applications layer
*
* Revision 1.2  2002/02/12 16:57:36  JasperV
* Updated version
*
* Revision 1.1  2002/01/24 14:18:14  travisb
* First Version of the Application Layer
*
* Revision 1.1  2002/01/21 08:06:07  travisb
* First version commited to CVS
*
*/

package blueprint4j.messages;

import java.io.*;
import java.util.*;
import java.math.*;
//import com.applications.comms.*;

public class Utils {
	static private String hex_vars = "0123456789ABCDEF";

	public static String convertLongToHex( long value ) {
		String ret = "";
		while ( value != 0 ) {
			int loworder = ( int ) ( value & 0xf );
			ret = hex_vars.substring( loworder, loworder + 1 ) + ret;
			value >>>= 4;
		}
		if ( ret.equals( "" ) ) {
			ret = "0";
		}
		return ret;
	}

	public static long convertHexToLong( String value )
	throws NumberFormatException {
		return Long.parseLong( value, 16 );
	}

	public static byte[] convertLongToBin( long value ) {
		byte [] b = new byte[ 8 ];
		for ( int t = 0, sr = 56;t < 8;t++, sr -= 8 ) {
			b[ t ] = (byte)(( value >>> sr ) & 255);
		}
		return b;
	}

	public static long convertBinToLong( byte[] b )
	throws NumberFormatException {
		//System.out.println(Integer.toString(b.length));
		if (b.length<8){
			throw new NumberFormatException("Only binary values with 8 bytes can be converted to longs");
		}

		long value = 0;
		for ( int t = 0, sl = 56;t < 8;t++, sl -= 8 ) {
			value |= ( ( long ) (b[ t ]&255) ) << sl ;
		}
		return value;
	}

	public static String convertByteToHex( byte value ) {
		String[] nums = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"};
		return nums[(value >> 4)&0xf] + nums[value&0xf];
	}

	public static String convertBytesToHex( byte value []) {
		String hex = "";
		for (int i = 0;i < value.length;i++) {
			hex = hex + convertByteToHex(value[i]);
		}
		return hex;
	}

	public static String convertBytesToHex( byte value [],int start,int end) {
		String hex = "";
		for (int i = start;i < end;i++) {
			hex = hex + convertByteToHex(value[i]);
		}
		return hex;
	}

	public static byte [] convertHexToByte(String message)
	throws NumberFormatException {
		while ((message.length()&1) == 1 || message.length() < 2) {
			message = "0" + message;
		}
		byte b[] = new byte[message.length() / 2];
		for (int t = 0;t < b.length;t++) {
			int msn = "0123456789ABCDEF".indexOf(message.substring(t * 2, t * 2 + 1).toUpperCase());
			int lsn = "0123456789ABCDEF".indexOf(message.substring(t * 2 + 1, t * 2 + 2).toUpperCase());
			if (msn == -1 || lsn == -1) {
				throw new NumberFormatException("Not a hex string [" + message + "]");
			}
			b[t] = (byte)((msn << 4) | lsn);
		}
		return b;
	}

	static void writeString( OutputStream output, String str )
	throws IOException {
		//System.out.println("Write: " + output + ":" + str);
		output.write( str.getBytes() );
	}

	static String readString( InputStream input, int size )
	throws IOException {
		return new String(readBytes( input, size ));
	}

	static byte[] readBytes( InputStream input, int size )
	throws IOException {
		byte[] bytes=new byte[size];
		int read=0;
		while (read<size){
			int gotnow=input.read(bytes,read,size-read);
			switch (gotnow){
			case -1:
				throw new IOException("Stream Closed ["+input.getClass().getName()+"]");
			case 0:
				throw new IOException("Stream Not Responding ["+input.getClass().getName()+"]");
			default:
				read+=gotnow;
			}
		}
		return bytes;
/*		ByteArrayOutputStream buffer=new ByteArrayOutputStream();
		byte[] bytes = null;
		int av=-1;
		byte b[] = new byte[ size ];
		try {
			av=input.available();
			int ms = 0;
			while ( size > 0 ) {
				if ( input.available() > 0 ) {
					int toread=size;
					if (toread>input.available()){
						toread=input.available();
					}
					int bytesin=input.read(b,0,toread);
					//System.out.println(new String(b));
					size-=bytesin;
					buffer.write(b,0,bytesin);
				} else {
					// Sleep for 5 ms
					try {
						Thread.sleep( 5 );
					} catch ( Exception e ) {}
					ms += 5;
					// Timeout after 300 secounds
					if ( ms > 300000) {
						throw new IOException( "Timeout on read from stream" );
					}
				}
			}
			bytes=buffer.toByteArray();
		}
		finally {
			if (bytes != null)
			Log.trace.out( "Utils Read", "Bytes Available="+av+" Bytes Read='"+new String(bytes)+"'");
		}
		return bytes;*/
	}

	/**
	 * Formats a Date from string yyyy.MM.dd hh.mm
	 */
	public static java.util.Date formatDateTime(String date,String time)
	throws ExceptionMessage {
		// Pad date with '.'
		if (date == null || date.length() != 8 || time == null || time.length()!=4)
			return null;
		date = date.substring(0,4) + "." + date.substring(4,6) + "." + date.substring(6,8);
		time = time.substring(0,2) + "." + date.substring(2,4);
		java.text.SimpleDateFormat simpleDateFormat = new java.text.SimpleDateFormat("yyyyMM.dd hh.mm");
		try {
			java.util.Date datetime = simpleDateFormat.parse(date + " " + time);
			return datetime;
		} catch (java.text.ParseException pe) {throw new ExceptionMessage("Incorrect date format yyyy.MM.dd hh.mm");}
	}

	public static String getYYYYMMDDFromDate(java.util.Date date) {
		java.text.SimpleDateFormat simpleDateFormat = new java.text.SimpleDateFormat("yyyy.MM.dd");
		String sdate = simpleDateFormat.format(date);
		return sdate.substring(0,4) + sdate.substring(5,7) + sdate.substring(8,10);
	}

	public static String getHHMMFromDate(java.util.Date date) {
		java.text.SimpleDateFormat simpleDateFormat = new java.text.SimpleDateFormat("hh.mm");
		String sdate = simpleDateFormat.format(date);
		return sdate.substring(0,2) + sdate.substring(3,5);
	}
}

